package com.ccl.keyassistant.activity;
/*
 *项目名     keyassistant
 *包名       com.ccl.keyassistant.activity
 *文件名     SendKeyActivity
 *创建者     ccl
 *创建时间   2019-03-14 15:37
 *注解       作为客户端连接，通过蓝牙将密码发送回PC
 */

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NavigationRes;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ccl.keyassistant.R;
import com.ccl.keyassistant.adapter.ScanAdapter;
import com.ccl.keyassistant.db.DBDataHelper;
import com.ccl.keyassistant.db.DBHelper;
import com.ccl.keyassistant.entity.BaseModel;
import com.ccl.keyassistant.entity.KeyModel;
import com.ccl.keyassistant.entity.MBluetoothDevice;
import com.ccl.keyassistant.utils.BluetoothService;
import com.ccl.keyassistant.utils.KeyUtil;
import com.ccl.keyassistant.utils.L;
import com.ccl.keyassistant.utils.StaticClass;
import com.ccl.keyassistant.view.CustomDialog;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Set;

public class SendKeyActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    //保存发现的蓝牙设备,返回的这个set是个只读的集合
    private Set<BluetoothDevice> pairedDevices;

    private List<MBluetoothDevice> mBlueDevices;
    private static BluetoothAdapter mBluethoothAdapter;
    //蓝牙扫描结束后，再次点击扫描时，scanAgain = false，清空存储数据
    private static boolean firstScan = true;
    private ListView mBlueListView;
    private Button mBlueBtn;
    private ScanAdapter scanAdapter;
    private CustomDialog dialog;
    private BluetoothService bluetoothService;
    private int clickItem;


    //蓝牙服务
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @RequiresApi(api = Build.VERSION_CODES.O)
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            switch (action) {
                case BluetoothDevice.ACTION_FOUND:
                    //获取额外的设备
                    BluetoothDevice extraDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                    //如果设备不在集合中则加入
                    if (!mBlueDevices.contains(new MBluetoothDevice(extraDevice))) {
                        mBlueDevices.add(new MBluetoothDevice(extraDevice));
                        L.i("添加新设备：" + extraDevice.getAddress());
                    }
//                L.i("设备已存在："+extraDevice.getAddress());
                    scanAdapter.notifyDataSetChanged();
                    break;

                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                    Toast.makeText(SendKeyActivity.this, "蓝牙扫描结束", Toast.LENGTH_SHORT).show();
                    break;
                //蓝牙绑定
                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:

                    if (dialog != null) {
                        dialog.dismiss();
                    }

                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
                    switch (state) {
                        case BluetoothDevice.BOND_BONDING:
                            Toast.makeText(context, "正在配对", Toast.LENGTH_SHORT).show();
                            break;
                        case BluetoothDevice.BOND_BONDED:
//                            Toast.makeText(context, "配对成功", Toast.LENGTH_SHORT).show();
                            Toast.makeText(context, "开始连接", Toast.LENGTH_SHORT).show();
                            //开始连接
                            bluetoothService.connect(mBlueDevices.get(clickItem).getBluetoothDevice());
                            if (dialog != null) {
                                dialog.dismiss();
                            }
//                            int states = bluetoothService.getState();
//                            L.i("state  " + states);

                            break;
                        default:
                            break;
                    }
                    break;

                case BluetoothDevice.ACTION_ACL_CONNECTED:


                    Toast.makeText(context, "蓝牙连接成功", Toast.LENGTH_SHORT).show();
                    //发送数据
                    if (bluetoothService != null) {
                        //由于线程锁的问题会导致 mState变量的值变化较慢，从而使得数据无法正常写出
                        //因此，需要在此处让线程睡眠一会，使得mState的值得以更新
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (bluetoothService.getState() == 2) {
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        L.i("thread state: " + bluetoothService.getState());
                        Intent data = getIntent();
                        String qrCodeInfo = data.getStringExtra("qrCodeInfo");
                        //判断加密还是解密
                        JSONObject jsonInfo = JSON.parseObject(qrCodeInfo);
                        String type = jsonInfo.getString("type");
                        if ("encrypt".equals(type)) {

                            //TODO 发送数据到pc端实现加密
                            /**
                             * 1 获取随机数
                             * 2 发送
                             * 3 添加结尾标识
                             */
                            byte[] random = KeyUtil.getRandom();
                            for (int i = 0; i < random.length; i++) {
                                L.i(random[i] + "");
                            }
                            bluetoothService.write(random);

                            //TODO 将密钥存储在数据库中

                            KeyModel key = new KeyModel();
                            key.file_name = jsonInfo.getString("fileName");
                            key.file_hash = jsonInfo.getString("fileHash");
                            key.remark = "pc file";
                            key.create_time = jsonInfo.getString("time");
                            key.en_type = jsonInfo.getString("enty");
                            //TODO 存储密钥
                            key.password = Base64.getEncoder().encodeToString(random);

                            //更新数据库
                            DBDataHelper helper = DBDataHelper.getInstance(getApplicationContext());
                            String whereCaluse = DBHelper.FILEHASH + " = ? and" + DBHelper.EN_TYPE + " = ?";
                            int update = helper.update(DBHelper.TABLE_KEY, whereCaluse, new String[]{
                                    key.file_hash, key.en_type
                            }, key);
                            if (update <= 0) {
                                helper.insert(
                                        DBHelper.TABLE_KEY, key
                                );
                            }
                        } else if ("decrypt".equals(type)) {
                            String hash = jsonInfo.getString("fileHash");
                            String enty = jsonInfo.getString("enty");
                            //解密，从数据库中查询
                            ArrayList<BaseModel> select = DBDataHelper.getInstance(getApplicationContext()).
                                    select(DBHelper.TABLE_KEY,
                                            new String[]{DBHelper.PASSWORD},
                                            DBHelper.FILEHASH + " = ? and" + DBHelper.EN_TYPE + " = ?"
                                            , new String[]{hash, enty}, null, KeyModel.class);

                            if (select != null && select.size() > 0) {
                                KeyModel model = (KeyModel) select.get(0);
                                //TODO 取出密钥
                                byte[] key = Base64.getDecoder().decode(model.password);
                                bluetoothService.write(key);
//                                for (int i = 0; i < key.length; i++) {
//                                    L.i(key[i] + "");
//                                }
                            } else {
                                bluetoothService.write(("NOSUCHFILE").getBytes());
                            }
                        }
                        //关闭蓝牙
                        bluetoothService.stop();
                        //退出当前activity

                        finish();
                    }
                    break;
                default:
                    break;
            }


        }
    };
    private CustomDialog dialog_load;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sendkey);

        //初始化ToolBar
        View tb = findViewById(R.id.sendkey_bar);
        Toolbar mToolBar = (Toolbar) tb.findViewById(R.id.toolbar);
        tb.findViewById(R.id.action_bar_left).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });

        //设置toolbar
        setSupportActionBar(mToolBar);
        //去掉默认显示的title
        getSupportActionBar().setDisplayShowTitleEnabled(false);


        //注册蓝牙发现服务
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy

        // 注册蓝牙扫描结束服务
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(mReceiver, filter);

        // 注册蓝牙绑定状态变化
        filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        this.registerReceiver(mReceiver, filter);

        // 注册蓝牙连接广播
        filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
        this.registerReceiver(mReceiver, filter);

    }


    //开启蓝牙
    public void openBluetooth(Context context) {
        //检查是否可以有蓝牙
        mBluethoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluethoothAdapter == null) {
            Toast.makeText(context, "设备不支持蓝牙", Toast.LENGTH_SHORT).show();
            return;
        }

        //检查蓝牙是否打开
        if (!mBluethoothAdapter.isEnabled()) {
            Intent blueIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            ((AppCompatActivity) context).startActivityForResult(blueIntent, StaticClass.BLUE_REQUEST_CODE);
        } else {

            getBindBlueDevice();
        }
    }

    //获取已经配对的蓝牙设备

    public void getBindBlueDevice() {
        //获取已经配对的蓝牙设备
        pairedDevices = mBluethoothAdapter.getBondedDevices();
        mBlueDevices = new ArrayList<MBluetoothDevice>();
        if (pairedDevices.size() > 0) {
            for (BluetoothDevice bd : pairedDevices) {
                mBlueDevices.add(new MBluetoothDevice(bd));
                L.i(bd.getName());
            }
        }

        View layout = View.inflate(this, R.layout.bluetooth_show_item, null);
        mBlueListView = (ListView) layout.findViewById(R.id.blue_scan_listview);
        mBlueBtn = (Button) layout.findViewById(R.id.blue_scan_btn);

        scanAdapter = new ScanAdapter(this, mBlueDevices);
        //设置数据适配器以及点击监听
        mBlueListView.setAdapter(scanAdapter);
        mBlueListView.setOnItemClickListener(this);
        //弹出一个dialog来显示蓝牙列表
        dialog = new CustomDialog(this, layout);
        dialog.show();
//        dialog.setCanceledOnTouchOutside(true);
        L.i(layout.getHeight() + "  " + layout.getWidth());
        mBlueBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //开启一个服务用来发现蓝牙设备
                if (!mBluethoothAdapter.isDiscovering()) {
                    boolean b = false;
                    if (firstScan) {
                        b = mBluethoothAdapter.startDiscovery();

                    } else {
                        mBlueDevices.clear();
                        for (BluetoothDevice bd : pairedDevices) {
                            mBlueDevices.add(new MBluetoothDevice(bd));
                        }
                        scanAdapter.notifyDataSetChanged();
                        b = mBluethoothAdapter.startDiscovery();
                    }
                    firstScan = !firstScan;
                    if (b) {
                        L.d("正在扫描");
                    }
                } else {
                    Toast.makeText(SendKeyActivity.this, "正在扫描中", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解绑
        unregisterReceiver(mReceiver);
    }


    //扫描点击事件
    public void scan(View view) {
        openBluetooth(this);
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

        bluetoothService = new BluetoothService(this);
        BluetoothDevice bluetoothDevice = mBlueDevices.get(i).getBluetoothDevice();

        int bondState = bluetoothDevice.getBondState();
        boolean bond = false;
        if (bondState != BluetoothDevice.BOND_BONDED) {
            bluetoothDevice.createBond();
        } else {
            bluetoothService.connect(mBlueDevices.get(i).getBluetoothDevice());
            if (dialog != null) {
                dialog.dismiss();
            }
            int state = bluetoothService.getState();
            L.i("state  " + state);
        }

        clickItem = i;

    }
}
